/*
 * Copyright (c) 2020 hebeiyiliuba.com
 * All rights reserved.
 *
 */
package org.jeecg.modules.middleware.quartz.job.djtax;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.third.dongjiang.tax.system.constant.TaxConstant;
import org.jeecg.modules.third.dongjiang.tax.system.constant.enums.PersonalIncomeTaxEnum;
import org.jeecg.modules.wlhy.bill.entity.HyShippingNoteBill;
import org.jeecg.modules.wlhy.bill.service.IHyShippingNoteBillService;
import org.jeecg.modules.wlhy.company.entity.HyCompanyDTO;
import org.jeecg.modules.wlhy.company.service.IHyCompanyService;
import org.jeecg.modules.wlhy.hyconfig.entity.HyConfig;
import org.jeecg.modules.wlhy.hydriver.entity.HyDriver;
import org.jeecg.modules.wlhy.hydriver.service.IHyDriverService;
import org.jeecg.modules.wlhy.hytaxdeclaration.entity.HyTaxDeclaration;
import org.jeecg.modules.wlhy.hytaxdeclaration.entity.HyTaxType;
import org.jeecg.modules.wlhy.hytaxdeclaration.service.IHyTaxDeclarationService;
import org.jeecg.modules.wlhy.hytaxpersonalincome.entity.HyTaxPersonalincome;
import org.jeecg.modules.wlhy.hytaxpersonalincome.entity.YssrTotalDTO;
import org.jeecg.modules.wlhy.hytaxpersonalincome.service.IHyTaxPersonalincomeService;
import org.jeecg.modules.wlhy.utils.HyConfigUtils;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 车主申报统计脚本+个人所得税
 *
 * @author duanlikao
 * @created 2021/3/20
 */
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class DriverDeclareStatService implements Job {

    private static final Logger LOGGER = LoggerFactory.getLogger(DriverDeclareStatService.class);

    public SimpleDateFormat now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    /**
     * 数额界限
     */
    private static BigDecimal AMOUNT_LIMIT = new BigDecimal("100000.00");
    /**
     * 税率 1.01
     * 2022-04-03临时修改 截止2022-12-31 1、【无税】和【有税】-申报表-增值税-计税依据修改为：【月收入/（1+0.03）】
     */
    private static BigDecimal COMMON_SL = new BigDecimal("1.01")  ;
    /**
     * 资金流水单
     */
    @Autowired
    private IHyShippingNoteBillService shippingNoteBillService;

    /**
     * 司机
     */
    @Autowired
    private IHyDriverService driverService;
    /**
     * 申报企业信息
     */
    @Autowired
    private  IHyCompanyService companyService;

    /**
     * 车主申报信息
     */
    @Autowired
    private  IHyTaxDeclarationService taxDeclarationService;

    /**
     * 车主个税明细申报信息
     */
    @Autowired
    private IHyTaxPersonalincomeService taxPersonalincomeService;



   // @Scheduled(cron =  "0/5 * * * * ? ")//每5秒执行一次
   // @Scheduled(cron = "0 0 0/1 * * ?") //每小时执行一次
   // @Scheduled(cron =  "0 */5 * * * ? ")//每5分中执行一次
//   @Scheduled(cron = "0 0 0 * * ?")//每天凌晨执行一次
//       @Scheduled(cron = "0 35 15 17 * ?")//每月1号的01:10:00执行
   //    @Scheduled(cron = "0 30 09 28 * ?")//每月1号的01:10:00执行

    //@Scheduled(cron = "0 10 2 2 * ?")//每月2号的02:10:00执行
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        HyConfig systemConfig = HyConfigUtils.getConfig();
        if (systemConfig == null || !systemConfig.getDongjiangIzUse()) {
            LOGGER.info("天津东疆税务上报服务暂未开启,请联系管理员。");
            return;
        }


        String[] dateTime = this.getDateTime().split("=");
        Date startTime = DateUtils.stringToDateTime(dateTime[0]);
        Date endTime = DateUtils.stringToDateTime(dateTime[1]);

        List<HyTaxType> hyTaxTypes = taxDeclarationService.queryTaxTypeData();
        if (CollectionUtils.isEmpty(hyTaxTypes)) {
            LOGGER.info("DriverDeclareStat:无税率数据");
            return;
        }

        List<HyShippingNoteBill> shippingNoteBills = shippingNoteBillService.driverDeclareStat(startTime, endTime);
        if (CollectionUtils.isEmpty(shippingNoteBills)) {
            LOGGER.info("DriverDeclareStat:无数据处理");
            return;
        }

        Long start = System.currentTimeMillis();
        LOGGER.info("DriverDeclareStat:执行统计数据开始" + now.format(new Date()));


        List<String> driverIds = shippingNoteBills.stream().map(HyShippingNoteBill::getDriverId).collect(Collectors.toList());

        int section = 30;
        List<HyDriver> hyDrivers = new LinkedList<>();
        for (int index = 0, end = 0; index < driverIds.size(); index = end) {
            end = (end + section) <= driverIds.size() ? end + section : driverIds.size();
            if (index < end) {
                hyDrivers.addAll(driverService.listByIds(driverIds.subList(index, end)));
            }
        }

        Map<String, HyDriver> hyDrivermaps = new HashMap<>();
        //for(HyDriver driver:hyDrivers)  hyDrivermaps.put(driver.getId(),driver);
        hyDrivermaps = hyDrivers.stream().collect(Collectors.toMap(HyDriver::getId, val -> val)); //, (k1, k2) -> k2

        for (HyShippingNoteBill shippingNoteBill : shippingNoteBills) {
            HyDriver driver = hyDrivermaps.get(shippingNoteBill.getDriverId());
            BigDecimal amt = shippingNoteBill.getAmt();
            if (amt == null || amt.compareTo(BigDecimal.ZERO) == 0 || driver == null) {
                continue;
            }
            for (HyTaxType taxType : hyTaxTypes) {
                this.saveTaxDeclaration(startTime, endTime, shippingNoteBill, driver, taxType);
            }//end HyTaxType
            //个人所得税详细信息
            this.savePersonalincome(shippingNoteBill, driver, startTime, endTime);

        }//end HyShippingNoteBill


        LOGGER.info("DriverDeclareStat:执行统计数据结束,耗时:" + (System.currentTimeMillis() - start) + "毫秒----");
    }


    /**
     * 保存车主申报数据
     * @param startTime
     * @param endTime
     * @param shippingNoteBill
     * @param driver
     * @param taxType
     */
    private void saveTaxDeclaration(Date startTime, Date endTime, HyShippingNoteBill shippingNoteBill, HyDriver driver,
            HyTaxType taxType) {
        HyTaxDeclaration taxDeclaration = new HyTaxDeclaration();

        if(StringUtils.isNotEmpty(driver.getFwfuuid())){
            taxDeclaration.setFwfuuid(driver.getFwfuuid());
        }else{
            taxDeclaration.setFwfuuid(TaxConstant.API_TAX_CUSTOMER_SUBFIX +driver.getId());
        }
        taxDeclaration.setBdzdwnsrsbh(driver.getIdcard());
        taxDeclaration.setBdzdwnsrmc(driver.getDriverName());
        taxDeclaration.setGjhdq("156");
        taxDeclaration.setZjlx("201");
        taxDeclaration.setZjhm(driver.getIdcard());
        taxDeclaration.setSshy("5431");
        taxDeclaration.setZsxm(taxType.getProjectCode());
        taxDeclaration.setZspm(taxType.getProjectSubclassCode());
        taxDeclaration.setZszm("");
        taxDeclaration.setSkssqq(startTime);
        taxDeclaration.setSkssqz(endTime);
        taxDeclaration.setYjse(BigDecimal.ZERO);// 已缴税额（默认填写 0）
        taxDeclaration.setSdzse(BigDecimal.ZERO);//  已代征税额（默认填写 0）
        taxDeclaration.setAmt(shippingNoteBill.getAmt());

        BigDecimal amt = shippingNoteBill.getAmt();
        BigDecimal amtNew = amt.divide(COMMON_SL ,4, BigDecimal.ROUND_HALF_UP);
        //大于等于十五万 有税
        if(amtNew.compareTo(AMOUNT_LIMIT) > -1){
            taxDeclaration.setIzTaxDeclaration("1");
            //2022-04-03临时注释 截止2022-12-31
            //taxDeclaration.setJmxz(taxType.getExemptionCode());
            if("10101".equals(taxType.getProjectCode())){
                this.getTaxed10101(amtNew, taxType, taxDeclaration);
                //2022-04-03临时添加 截止2022-12-31  3、【有税】-申报表-增值税-减免性质代码改为：【0001045308】
                //2023-01-12 增值税-计税-减免性质代码改为【0001011608】
                taxDeclaration.setJmxz("0001011608");
            }else if("10111".equals(taxType.getProjectCode())){
                this.getTaxed10111(amt, taxType, taxDeclaration);
                //2022-04-03临时添加 截止2022-12-31
                taxDeclaration.setJmxz(taxType.getExemptionCode());
            }else{
                this.getTaxed10109(amtNew, taxType, taxDeclaration);
                taxDeclaration.setJmxz(taxType.getExemptionCode());
                //2022-04-03临时添加 截止2022-12-31 5、【有税】-申报表-城建税、教育附加税、地方教育附加税-改为：与【无税】申报表三种附税一致，默认填写0
                //this.get10109( taxType, taxDeclaration);
                //taxDeclaration.setJmxz("");
            }
//            LOGGER.info("saveTaxDeclaration taxDeclaration:{} " , JSONObject.toJSONString(taxDeclaration));
            taxDeclarationService.save(taxDeclaration);
        }else{//无税
              taxDeclaration.setIzTaxDeclaration("0");
              if("10101".equals(taxType.getProjectCode())){
                  this.get10101(amtNew, taxType, taxDeclaration);
                  taxDeclaration.setJmxz(taxType.getExemptionCode());
              }else if("10111".equals(taxType.getProjectCode())){
                  this.get10111(amt, taxType, taxDeclaration);
                  taxDeclaration.setJmxz(taxType.getExemptionCode());
              }else{
                  this.get10109( taxType, taxDeclaration);
                  taxDeclaration.setJmxz("");
              }
//            LOGGER.info("saveTaxDeclaration taxDeclaration:{} " , JSONObject.toJSONString(taxDeclaration));
            taxDeclarationService.save(taxDeclaration);

        }
    }

    /**
     * 有税 城建税 教育附加税 地方教育附加税
     * @param amt
     * @param taxType
     * @param taxDeclaration
     */
    private void getTaxed10109( BigDecimal amt, HyTaxType taxType, HyTaxDeclaration taxDeclaration) {
        BigDecimal slhse = taxType.getTaxAmount();
        BigDecimal jsyj = amt.multiply(new BigDecimal("0.01"));
        //计税依据
        taxDeclaration.setJsyj(jsyj.setScale(2, BigDecimal.ROUND_HALF_UP));
        //  税率或税额
        taxDeclaration.setSlhse(slhse.setScale(4, BigDecimal.ROUND_HALF_UP));
        // 应纳税额 (计税依据 * 对应税种税率)
        BigDecimal ynse = jsyj.multiply(slhse);
        taxDeclaration.setYnse(ynse.setScale(2, BigDecimal.ROUND_HALF_UP));
        //  减免税额
        BigDecimal jmse = ynse.divide(new BigDecimal("2"),4, BigDecimal.ROUND_HALF_UP);
        taxDeclaration.setJmse(jmse.setScale(2, BigDecimal.ROUND_HALF_UP));
        //  应代征税额 （应纳税额 - 减免税额）
        BigDecimal ydzse = ynse.subtract(jmse);
        taxDeclaration.setYdzse(
                ydzse.compareTo(BigDecimal.ZERO) > 0 ? ydzse.setScale(2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO
        );
    }

    /**
     * 有税 印花税
     * @param amt
     * @param taxType
     * @param taxDeclaration
     */
    private void getTaxed10111(BigDecimal amt, HyTaxType taxType, HyTaxDeclaration taxDeclaration) {
        BigDecimal jsyj = amt;
        BigDecimal slhse = taxType.getTaxAmount();
        //计税依据
        taxDeclaration.setJsyj(jsyj.setScale(2, BigDecimal.ROUND_HALF_UP) );
        //  税率或税额
        taxDeclaration.setSlhse(slhse.setScale(4, BigDecimal.ROUND_HALF_UP) );
        //  应纳税额 (计税依据 * 对应税种税率)
        BigDecimal ynse =   jsyj.multiply(slhse);
        taxDeclaration.setYnse(ynse.setScale(2, BigDecimal.ROUND_HALF_UP)
        );
        //  减免税额
        BigDecimal jmse = ynse.divide(new BigDecimal("2"),4, BigDecimal.ROUND_HALF_UP);
        taxDeclaration.setJmse(
                jmse.compareTo(BigDecimal.ZERO) > 0 ? jmse.setScale(2, BigDecimal.ROUND_HALF_UP) :BigDecimal.ZERO
        );
        //  应代征税额 （应纳税额 - 减免税额）
        BigDecimal  ydzse  =  ynse.subtract(jmse);
        taxDeclaration.setYdzse(
                ydzse.compareTo(BigDecimal.ZERO) > 0 ? ydzse.setScale(2, BigDecimal.ROUND_HALF_UP): BigDecimal.ZERO
        );

    }

    /**
     * 有税 增值税
     * @param amt
     * @param taxType
     * @param taxDeclaration
     */
    private void getTaxed10101(BigDecimal amt, HyTaxType taxType, HyTaxDeclaration taxDeclaration) {
        BigDecimal jsyj = amt;
        BigDecimal slhse = taxType.getTaxAmount();
        //计税依据
        taxDeclaration.setJsyj(jsyj.setScale(2, BigDecimal.ROUND_HALF_UP) );
        //  税率或税额
        taxDeclaration.setSlhse(slhse.setScale(4, BigDecimal.ROUND_HALF_UP) );
        // 应纳税额 (计税依据 * 对应税种税率)
        BigDecimal ynse =   jsyj.multiply(slhse);
        taxDeclaration.setYnse(ynse.setScale(2, BigDecimal.ROUND_HALF_UP)  );
        //  减免税额 有税申报时：减免税额 =0；
        //BigDecimal jmse =  BigDecimal.ZERO;
        //2022-04-03临时修改 截止2022-12-31  4、【有税】-申报表-增值税-减免税额改为：【月收入/（1+0.03）】
        BigDecimal jmse =  amt;
        taxDeclaration.setJmse(jmse.setScale(2, BigDecimal.ROUND_HALF_UP));
        //  应代征税额 （应纳税额 - 减免税额）
        BigDecimal  ydzse  =  ynse.subtract(jmse);
        taxDeclaration.setYdzse(
                ydzse.compareTo(BigDecimal.ZERO) > 0 ? ydzse.setScale(2, BigDecimal.ROUND_HALF_UP): BigDecimal.ZERO
        );

    }

    /**
     * 无税 印花税
     * @param amt
     * @param taxType
     * @param taxDeclaration
     */
    private void get10111(BigDecimal amt, HyTaxType taxType, HyTaxDeclaration taxDeclaration) {
        BigDecimal jsyj = amt;
        BigDecimal slhse = taxType.getTaxAmount();
        //计税依据
        taxDeclaration.setJsyj(jsyj.setScale(2, BigDecimal.ROUND_HALF_UP) );
        //  税率或税额
        taxDeclaration.setSlhse(slhse.setScale(4, BigDecimal.ROUND_HALF_UP)
        );
        // 应纳税额 (计税依据 * 对应税种税率)
        BigDecimal ynse =   jsyj.multiply(slhse);
        taxDeclaration.setYnse(ynse.setScale(2, BigDecimal.ROUND_HALF_UP) );
        //  减免税额 无税申报时：减免税额 = 应纳税额）
        BigDecimal jmse = ynse.divide(new BigDecimal("2"),4, BigDecimal.ROUND_HALF_UP);
        taxDeclaration.setJmse(
                jmse.compareTo(BigDecimal.ZERO)  > 0 ? jmse.setScale(2, BigDecimal.ROUND_HALF_UP) :BigDecimal.ZERO
        );
        //  应代征税额 （应纳税额 - 减免税额）
        BigDecimal  ydzse  =  ynse.subtract(jmse);
        taxDeclaration.setYdzse(
                ydzse.compareTo(BigDecimal.ZERO)  > 0 ? ydzse.setScale(2, BigDecimal.ROUND_HALF_UP): BigDecimal.ZERO
        );

    }

    /**
     * 无税 增值税
     * @param amt
     * @param taxType
     * @param taxDeclaration
     */
    private void get10101(BigDecimal amt, HyTaxType taxType, HyTaxDeclaration taxDeclaration) {
        BigDecimal jsyj = amt;
        //计税依据
        taxDeclaration.setJsyj(jsyj.setScale(2, BigDecimal.ROUND_HALF_UP)
        );
        //  税率或税额
        BigDecimal slhse =   taxType.getTaxAmount();
        taxDeclaration.setSlhse(slhse.setScale(4, BigDecimal.ROUND_HALF_UP)
        );
        // 应纳税额 (计税依据 * 对应税种税率)
        BigDecimal ynse =   jsyj.multiply(slhse);
        taxDeclaration.setYnse(
              ynse.setScale(2, BigDecimal.ROUND_HALF_UP)
        );
        //  减免税额 无税申报时：减免税额 = 应纳税额）
        BigDecimal jmse = ynse;
        taxDeclaration.setJmse(jmse.setScale(2, BigDecimal.ROUND_HALF_UP));
        //  应代征税额 （应纳税额 - 减免税额）
        BigDecimal  ydzse  =  ynse.subtract(jmse);
        taxDeclaration.setYdzse(
                ydzse.compareTo(BigDecimal.ZERO) > 0 ?   ydzse.setScale(2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO
        );

    }

    /**
     * 无税 城建税 教育附加税 地方教育附加税
     * @param taxType
     * @param taxDeclaration
     */
    private void get10109( HyTaxType taxType, HyTaxDeclaration taxDeclaration) {
        BigDecimal slhse = taxType.getTaxAmount();
        //计税依据
        taxDeclaration.setJsyj(BigDecimal.ZERO);
        //  税率或税额
        taxDeclaration.setSlhse(slhse.setScale(4, BigDecimal.ROUND_HALF_UP));
        // 应纳税额 (计税依据 * 对应税种税率)
        taxDeclaration.setYnse(BigDecimal.ZERO);
        //  减免税额
        taxDeclaration.setJmse(BigDecimal.ZERO);
        //  应代征税额 （应纳税额 - 减免税额）
        taxDeclaration.setYdzse(BigDecimal.ZERO);
    }

    /**
     * 个人所得税详细信息
     * @param shippingNoteBill
     * @param driver
     * @param startTime
     * @param endTime
     */
    private  void savePersonalincome(HyShippingNoteBill shippingNoteBill, HyDriver driver, Date startTime, Date endTime){
        //申报公司：河北一六八网络科技有限公司天津第二分公司
        HyCompanyDTO company   = companyService.getCompanyAndConfig(
                new HyCompanyDTO()
                        .setCompanyId(shippingNoteBill.getCompanyId())
                        .setTaxUploadType(1)
                        .setTaxTjUploadStatus("1")
        );

        HyTaxPersonalincome taxPersonalincome = new HyTaxPersonalincome();

        taxPersonalincome.setNsrsbh(company.getCreditCode());// 是 纳税人识别号（平台企业）
        taxPersonalincome.setNsrmc(company.getCompanyName());// 是 纳税人名称（平台企业）
        taxPersonalincome.setHy("5431");// 是 行业（平台企业）-填写行 业代码，参见《行业代码- 名称表》 2019-5-15 说明
        taxPersonalincome.setXzqh("120116");// 是 行政区划（平台企业）- 填写行政区划代码（市 级），参见《行政区划代码 -名称表》 （默认：120116） 2019-5-15 说明
        taxPersonalincome.setJdxz(company.getDetailAddress());// 是 街道乡镇（平台企业）
        taxPersonalincome.setSwjg(company.getZgswjg());// 是 税务机关（平台企业）


        //司机
        String fwfuuid=null;
        if(StringUtils.isNotEmpty(driver.getFwfuuid())){
            fwfuuid=driver.getFwfuuid();
        }else{
            fwfuuid=TaxConstant.API_TAX_CUSTOMER_SUBFIX +driver.getId();
        }
        taxPersonalincome.setFwfuuid(fwfuuid);
        // 是 对应服务方唯一标识 fwfuuid
        taxPersonalincome.setSfzjlx("201");// 是 身份证件类型（自然人）- 填写身份证件种类代码， 参见《申报表-计税 excel 页签：证件代码表》
        taxPersonalincome.setSfzjhm(driver.getIdcard());// 是 身份证件号码（自然人）
        taxPersonalincome.setXm(driver.getDriverName());// 是 姓名（自然人）
        taxPersonalincome.setGjdq("156");// 是 国籍（地区）（自然人）- 填写国家地区代码，参见 《申报表-计税 excel 页 签：国家和地区代码》 （默认填写：156） 2019-5-15 说明
        taxPersonalincome.setLxdh(driver.getTelephone());// 是 联系电话（自然人）
        taxPersonalincome.setScjydxzqh("120116");// 是 生产经营地行政区划（至 省、直辖市，取个人当年 第一次申报所属行政区 划）（自然人默认填写 120116（东疆行政区划））

        taxPersonalincome.setSbrq(new Date());// 是 申报日期
        taxPersonalincome.setSkssqq(startTime);// 是 税款所属期起。到月份第 一天（例：2020-01-01）
        taxPersonalincome.setSkssqz(endTime);// 是 税款所属期止。到月份最 后一天（例：2020-01-31）
        taxPersonalincome.setAmt(shippingNoteBill.getAmt());

        BigDecimal amt  =  shippingNoteBill.getAmt();

        YssrTotalDTO yssrTotalDTO = this.getTaxPersonalincomeByFwfuuid(fwfuuid);
        BigDecimal  yssrTotal =  yssrTotalDTO != null && yssrTotalDTO.getYssr()!= null ?  yssrTotalDTO.getYssr() : BigDecimal.ZERO;
        taxPersonalincome.setYssrTotal(yssrTotal.setScale(2, BigDecimal.ROUND_HALF_UP) );
        //  应税收入(自然人当年累计收入)计算方式：从当年1月份 到本月的应税收入累计，其中每月的应税收入计算规则为：
        //  如果该月份订单累计金额/1.03<=10W 则该月应税收入为订单累计金额；
        //  如果该月份订单累计金额/1.03>10W 则该月应税收入为订单累计金额/1.03；
        //Double yssr =  ( amt + yssrTotal ) <= AMOUNT_LIMIT.doubleValue() ? ( amt + yssrTotal ) : ( amt + yssrTotal ) / COMMON_SL ;

        //小于等于
        // 2022-04-03临时注释 截止2022-12-31  6、个税明细-应税收入改为，全部为订单累计金额，即当月的订单金额+上月的应税收入，当月订单金额不需要除任何数
        //BigDecimal  amtTmp = amt.compareTo(AMOUNT_LIMIT) < 1 ? amt  :  amt.divide(COMMON_SL,4, BigDecimal.ROUND_HALF_UP)  ;
        BigDecimal  amtTmp =  amt    ;
        BigDecimal yssr =   amtTmp.add(yssrTotal)  ;
        taxPersonalincome.setYssr(
                yssr.compareTo(BigDecimal.ZERO)  > 0 ?  yssr.setScale(2, BigDecimal.ROUND_HALF_UP) :  BigDecimal.ZERO
        );
        BigDecimal rssdl = new BigDecimal("0.05");
        taxPersonalincome.setYssdl( rssdl );//  应税所得率 默认 5%，如有变更，以最 新政策为准 2020-5-1 说明
        // 计税依据 (应税收入 * 应税所得率)
        BigDecimal jsyj = yssr.multiply(rssdl);
        taxPersonalincome.setJsyj(jsyj.setScale(2, BigDecimal.ROUND_HALF_UP) );

        BigDecimal sl  =  BigDecimal.ZERO;
        BigDecimal sks =  BigDecimal.ZERO;
        Map<String,String>  slAndsksMap = this.getSlAndsks(jsyj) ;
        LOGGER.debug("savePersonalincome  jsyj :{},slAndsksMap :{}" ,jsyj, slAndsksMap.toString());
        for(String key : slAndsksMap.keySet()) {
            sl = new BigDecimal(key);
            sks = new BigDecimal(slAndsksMap.get(key));
            break;
        }

        //  税率(需将百分比换算成小数) (速算表)
        taxPersonalincome.setSl(sl.setScale(2, BigDecimal.ROUND_HALF_UP)
        );
        //  速算扣除数 (生产经营所得) 速算表
        taxPersonalincome.setSskcs(sks.setScale(2, BigDecimal.ROUND_HALF_UP)
        );
        //  应纳税额 (计税依据 * 速算表税率 - 速算扣除数)
        BigDecimal temp = jsyj.multiply(sl);
        BigDecimal ynse = temp.subtract(sks);
        taxPersonalincome.setYnse( ynse.setScale(2, BigDecimal.ROUND_HALF_UP) );
        //  累计已缴税额 （之前各月已缴纳个税总和例如：
        //  一月设为当年初始申报，默认为零
        //  二月为一月份的应缴纳个税金额（即 1月份的 本期应补退税额，若该自然人一月 未申报则为 0）
        //  三月份为一月份与二月份的应缴纳个税金额累计（即 1 月份的 本期应补退税额+2 月份的 本期应补退税额。
        // 若之前该用户全 未申报个税则为 0，否 则累计）其他月份以此类推
        BigDecimal ljyjse =  yssrTotalDTO != null && yssrTotalDTO.getBqybtse()!= null ?  yssrTotalDTO.getBqybtse() : BigDecimal.ZERO;
        taxPersonalincome.setLjyjse(ljyjse.setScale(2, BigDecimal.ROUND_HALF_UP)  );
        // 本期应补退税额 （应纳税额 - 累计已缴税额）
        BigDecimal bqybtse = ynse.subtract(ljyjse) ;
        taxPersonalincome.setBqybtse(
                bqybtse.compareTo(BigDecimal.ZERO) > 0 ?  bqybtse.setScale(2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO
        );
        LOGGER.debug("savePersonalincome  taxPersonalincome:{}" , JSONObject.toJSONString(taxPersonalincome));
        taxPersonalincomeService.save(taxPersonalincome);
    }



    /**
     * 统计司机每月已经个税 累计已缴税额
     * @param fwfuuid
     * @return
     */
    private  YssrTotalDTO  getTaxPersonalincomeByFwfuuid(String fwfuuid){

        String[]  yearMonth = this.getStaYearMonth().split("=");
        YssrTotalDTO yssrTotalDTO =  taxPersonalincomeService.getTaxPersonalincomeByFwfuuid(fwfuuid,yearMonth[0],yearMonth[1]);
        LOGGER.debug("getTaxPersonalincomeByFwfuuid yssrTotalDTO:{},fwfuuid:{}, startMonth:{},  endMonth:{}  ",
                yssrTotalDTO ,fwfuuid ,yearMonth[0],yearMonth[1]);
        return yssrTotalDTO;
    }


    /**
     * 获取统计时间段
     * @return
     */
    private String getDateTime(){
        int lastMonth  = Calendar.getInstance().get(Calendar.MONTH);
        return DateUtils.getFirstDayOfMonth(lastMonth) +"="+DateUtils.getLastDayOfMonth(lastMonth);
        //return "2023-01-01 00:00:00=2023-01-31 23:59:59";
    }

    /**
     * 获取统计一年中开始月份到上个月的时间段
     * @return
     */
    private String getStaYearMonth(){
        int nowYear  = Calendar.getInstance().get(Calendar.YEAR);
        int lastMonth  = Calendar.getInstance().get(Calendar.MONTH);
        //当前月是1月
        if(lastMonth == 0){
            nowYear = nowYear -1;
            lastMonth = 12;
        }

        String startMonth = nowYear+"-01";
        String endMonth =  nowYear+"-"+ DateUtils.fillZero(lastMonth);
        return startMonth +"="+endMonth;
    }




    /**
     * 获取个税的速算税率和速算数
     * @param jsyj
     * @return
     */
    private  Map<String,String> getSlAndsks(BigDecimal jsyj) {
        Map <String, String> slAndsks = new HashMap <>();
        int code = 0;

        //if (jsyj < 30000.00d) {
        //    code = 1;
        //} else if (jsyj >= 30000.00d && jsyj < 90000.00d) {
        //    code = 2;
        //} else if (jsyj >= 90000.00d && jsyj < 300000.00d) {
        //    code = 3;
        //} else if (jsyj >= 300000.00d && jsyj < 500000.00d) {
        //    code = 4;
        //} else if (jsyj >= 500000.00d) {
        //    code = 5;
        //}

        BigDecimal threew = new BigDecimal("30000.00");
        BigDecimal ninew = new BigDecimal("90000.00");
        BigDecimal thirtyw = new BigDecimal("300000.00");
        BigDecimal fiftyw = new BigDecimal("500000.00");
        //小于三万
        if (jsyj.compareTo(threew ) == -1 ) {
            code = 1;
        //大于等于三万-小于九万之间
        } else if (jsyj.compareTo(threew) > -1  && jsyj.compareTo(ninew ) == -1 ) {
            code = 2;
        //大于等于九万-小于三十万之间
        } else if (jsyj.compareTo(ninew) > -1  && jsyj.compareTo(thirtyw ) == -1 ) {
            code = 3;
        //大于等于三十万-小于五十万之间
        } else if (jsyj.compareTo(thirtyw) > -1 && jsyj.compareTo(fiftyw ) == -1) {
            code = 4;
        //大于等于五十万
        } else if (jsyj.compareTo(fiftyw) > -1 ) {
            code = 5;
        }
        PersonalIncomeTaxEnum personalIncomeTaxEnum = PersonalIncomeTaxEnum.getPersonalIncomeTaxEnumByVal(code);
        slAndsks.put(personalIncomeTaxEnum.getSl(),personalIncomeTaxEnum.getSks());
        return slAndsks;
    }





}
